package monitorcon

import (
	"github.com/go-redis/redis"
	"log"
	"strconv"
)

//MAXCONNECTLABEL : 最大连接数标签
const MAXCONNECTLABEL string = "monitor_maxcons"
//MAXCONNUM :最大连接数
const MAXCONNUM int = 100

//LIVECONNNUMLABEL :活跃实例连接数
const LIVECONNNUMLABEL string = "liveconnum"
//DATAPERIODLABEL :数据存入db的时间标签
const DATAPERIODLABEL string = "datamonitortime"
//DEVICELISTKEY :监控的设备列表
const DEVICELISTKEY string = "alldevices"
//SUBSCRIBFIELDLIST :订阅的设备field列表
const SUBSCRIBFIELDLIST string = "subcribefieldlists"
//SUBSCRIBFIELDITEMLIST :订阅的设备field的position列表
const SUBSCRIBFIELDITEMLIST string = "subcribefielditemlists"

//RedisManager class: redis操作管理类
type RedisManager struct {
	rs     *redis.Client
	maxnum int
}

//ReceiveClient 得到redis client
func (r *RedisManager) ReceiveClient(client *redis.Client) {
	r.rs = client
	return
}

//CreateClient 创建redis client
func (r *RedisManager) CreateClient() {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0, //dbindex=0
		//PoolSize: 20,
	})

	// 通过 cient.Ping() 来检查是否成功连接到了 redis 服务器
	pong, err := client.Ping().Result()
	log.Println(pong, err)
	r.rs = client
	return
}

//GetClient 返回redis client
func (r *RedisManager) GetClient() *redis.Client {
	return r.rs
}

//ReceiveClient 得到redis client
func (r *RedisManager) setRedisClient(rsclient *redis.Client) {
	r.rs = rsclient
	// r.maxnum=100; //default max connection num
}

//SetMaxconnum :设置最大连接数
func (r *RedisManager) SetMaxconnum(maxconnum int) error {
	r.maxnum = maxconnum
	err := r.rs.Set(MAXCONNECTLABEL, maxconnum, 0).Err() //设置最大连接数

	if err != nil {
		//panic(err)
		log.Println(err)
		return err
	}

	return nil

}

//GetMaxconnum :返回最大连接数
func (r *RedisManager) GetMaxconnum() (int, error) {
	maxnum, err := r.rs.Get(MAXCONNECTLABEL).Result()

	imax, err := strconv.Atoi(maxnum)
	if err != nil {
		log.Println(err)
		return -1, err
	}

	return imax, err

}

//SetInstancefield  set 实例 field node in redis
func (r *RedisManager) SetInstancefield(keynum string, datavalue map[string]interface{}) {
	key := MLABEL + keynum
	r.rs.HMSet(key, datavalue)
}

//GetInstancefield return 实例 field node in redis
func (r *RedisManager) GetInstancefield(keynum string, field string) (string, error) {
	key := MLABEL + keynum
	return r.rs.HGet(key, field).Result()
}

//DelInstancefield delete 实例 key
func (r *RedisManager) DelInstancefield(keynum string) {
	key := MLABEL + keynum
	r.rs.Del(key)
	return
}

//Exists 判断实例key是否存在
func (r *RedisManager) Exists(keynum string) int {
	key := MLABEL + keynum
	var flag int64
	flag, _ = r.rs.Exists(key).Result()

	return int(flag)
}

//SetDevicefield set 设备信息  in redis
func (r *RedisManager) SetDevicefield(key string, datavalue map[string]interface{}) {

	r.rs.HMSet(key, datavalue)
}

//GetDevicefield return 设备信息  in redis
func (r *RedisManager) GetDevicefield(key string, field string) (string, error) {

	return r.rs.HGet(key, field).Result()
}

//SetSinglefield ...
func (r *RedisManager) SetSinglefield(key string, value string) {
	r.rs.Set(key, value, 0)
}

//DelSinglefield ...
func (r *RedisManager) DelSinglefield(key string) {
	r.rs.Del(key)
}

//GetSinglefield ...
func (r *RedisManager) GetSinglefield(key string) (string, error) {
	num, err := r.rs.Get(key).Result()
	if err != nil {
		log.Println(err)
		return "", err
	}

	return num, err
}

//GetValueFromList 从实例列表中得到指定的设备内容
func (r *RedisManager) GetValueFromList(keynum string, index int) (string, error) {
	key := MLABEL + keynum + "_list"
	hostinfo, err := r.rs.LIndex(key, int64(index)).Result() //得到指定实例的设备内容
	return hostinfo, err
}
//RemoveFromlist 从实例列表中删除指定的设备内容
func (r *RedisManager) RemoveFromlist(keynum string, value string) {
	key := MLABEL + keynum + "_list"
	r.rs.LRem(key, 0, value) // 移除表中所有与 VALUE 相等的值。
}

//Setlistvalue 在实例列表中更新设备内容
func (r *RedisManager) Setlistvalue(keynum string, index int, value string) {
	key := MLABEL + keynum + "_list"
	log.Printf("Setlistvalue:key=%s,index=%d,value=%s", key, index, value)

	r.rs.LSet(key, int64(index), value) 
}

//Delinsdevicelist 删除实例管理的devicelist
func (r *RedisManager) Delinsdevicelist(keynum string) {
	key := MLABEL + keynum + "_list"
	r.rs.Del(key)
}

//Pushtodevicelist 推设备信息到实例管理的devicelist头部
func (r *RedisManager) Pushtodevicelist(keynum string, value string) {
	key := MLABEL + keynum + "_list"
	r.rs.LPush(key, value)
}

//Appendtolist 推设备信息到实例管理的devicelist尾部
func (r *RedisManager) Appendtolist(keynum string, value string) {
	key := MLABEL + keynum + "_list"
	r.rs.RPush(key, value) //追加到尾部
}

//Appendtodevicelists 推hostuuid到devicelist
func (r *RedisManager) Appendtodevicelists(key string, hostuuid string) {

	r.rs.RPush(key, hostuuid)
}

//Removefromdevicelists 从devicelist删除指定hostuuid
func (r *RedisManager) Removefromdevicelists(key string, hostuuid string) {

	r.rs.LRem(key, 0, hostuuid)
}

//Deldevicelists 删除某个设备的devicelist
func (r *RedisManager) Deldevicelists(key string) {

	r.rs.Del(key)
}

//Delsubscribelists 删除某个订阅设备的devicelist
func (r *RedisManager) Delsubscribelists(key string) {

	r.rs.Del(key)
}

//SubscribeDevicefield 保存订阅的设备信息到订阅列表
func (r *RedisManager) SubscribeDevicefield(fieldvalue string) {
	r.rs.RPush(SUBSCRIBFIELDLIST, fieldvalue)
}

//Getsubscribedfieldlists 返回订阅设备信息列表
func (r *RedisManager) Getsubscribedfieldlists() map[string]string {
	listlen, err := r.rs.LLen(SUBSCRIBFIELDLIST).Result()
	if err != nil {
		return nil
	}
	//llen, err := strconv.Atoi(listlen)

	var elm string
	map1 := make(map[string]string)
	var i = 0
	for i = 0; i < int(listlen); i++ {
		elm, err = r.rs.LIndex(SUBSCRIBFIELDLIST, int64(i)).Result()
		map1[elm] = elm
	}

	return map1

}
//SubscribeDevicefielditem 保存订阅的设备item信息到订阅列表
func (r *RedisManager) SubscribeDevicefielditem(itemvalue string) {
	r.rs.RPush(SUBSCRIBFIELDITEMLIST, itemvalue)
}

//Getsubscribedfielditemlists 返回订阅设备信息item列表
func (r *RedisManager) Getsubscribedfielditemlists() map[string]string {
	listlen, err := r.rs.LLen(SUBSCRIBFIELDITEMLIST).Result()
	if err != nil {
		return nil
	}
	//llen, err := strconv.Atoi(listlen)

	var elm string
	map1 := make(map[string]string)
	var i = 0
	for i = 0; i < int(listlen); i++ {
		elm, err = r.rs.LIndex(SUBSCRIBFIELDITEMLIST, int64(i)).Result()
		map1[elm] = elm
	}

	return map1

}
//Deviceinlists 设备是否在设备列表中,或设备信息是否在订阅列表中
func (r *RedisManager) Deviceinlists(key string, field string) bool {

	listlen, err := r.rs.LLen(key).Result()
	if err != nil {
		return false
	}
	//llen, err := strconv.Atoi(listlen)

	var elm string
	var flag = false
	var i = 0
	for i = 0; i < int(listlen); i++ {
		elm, err = r.rs.LIndex(key, int64(i)).Result()
		if elm == field {
			flag = true
			break
		}
	}

	return flag
}
